//#pragma once
#ifndef __M_SERVER_H__
#define __M_SERVER_H__
/**
 * 目前整体编写，后序分文件
*/
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <cstring> 
#include <functional>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <typeinfo>
#include <memory>
#include <unordered_map>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include "any.hpp"
#include "log.hpp"
#include "err.hpp"

//Buffer模块
#define BUFFER_DEFAULT_SIZE 1024

const static int backlog = 32;

class Buffer
{
public:
    Buffer():_buffer(BUFFER_DEFAULT_SIZE),_reader_idx(0),_writer_idx(0) {}
    //获取起始地址
    char *Begin() {return &*_buffer.begin(); }
    //获取当前写入起始地址
    char *WritePosition() { return Begin() + _writer_idx; }
    //获取当前读取起始地址
    char *ReadPosition() { return Begin() + _reader_idx; }
    //获取前沿空闲空间大小----写偏移之后的空闲空间
    uint64_t TailIdleSize() {return _buffer.size() - _writer_idx; }
    //获取后沿空闲空间大小----读偏移之前的空闲空间
    uint64_t HeadIdleSize() {return _reader_idx; }
    //获取可读数据大小
    uint64_t ReadAbleSize() {return _writer_idx - _reader_idx; }
    //将读偏移向后移动
    void MoveReadOffest(uint64_t len)
    {
        if(len == 0) return;
        assert(len <= ReadAbleSize());
        _reader_idx += len;
    }
    //将写偏移向后移动
    void MoveWriteOffest(uint64_t len)
    {
        /*先只判断前沿空间大小*/
        assert(len <= TailIdleSize());
        _writer_idx += len;
    }
    //确保可写空间大小足够(先判断剩余空闲大小是否足够，不够就扩容)
    void EnsureWriteSpace(uint64_t len)
    {
        /*如果待写数据小于前沿空间，直接返回即可*/
        if(TailIdleSize() >= len) return;
        /*走到此表示只靠前沿空间不够，那就把后沿空间加上判断*/
        if(len <= TailIdleSize() + HeadIdleSize())
        {
            //把数据移动到起始位置
            uint64_t read_copy = ReadAbleSize();//先拿到可读数据大小
            /*std::copy()函数-->1.起始位置 2.终点位置 3.移到哪里的起始位置*/
            std::copy(ReadPosition(),ReadPosition()+read_copy,Begin());
            _reader_idx = 0;//将读偏移置为0
            _writer_idx = read_copy;//将写位置改到可读数据大小，因为当前写起始位置就是之前可读数据大小的位置
        }
        else/*这里就直接扩容,因为全部大小都不够*/
        {
            logMessage(DEBUG,"resize %ld",_writer_idx + len);
            _buffer.resize(_writer_idx + len);//不移动数据，直接在写偏移之后扩容
        }
    }
    //写入数据
    void Write(void *data, uint64_t len)
    {
        //1.先判断空间大小
        if(len == 0) return;
        EnsureWriteSpace(len);
        //2.拷贝数据进去
        const char* d = (const char*) data;
        std::copy(d,d + len,WritePosition());
        //std::copy((const char*)data,(const char*)data + len,WritePosition());
    }
    //更新写入数据后的位置
    void WriteAndPush(void *data, uint64_t len)
    {
        Write(data,len);
        MoveWriteOffest(len);
    }
    //写入字符串数据
    void WriteString(const std::string &data)
    {
        return Write((void*)data.c_str(),data.size());
    }
    //更新写入数据后的位置
    void WriteStringAndPush(const std::string &data)
    {
        WriteString(data);
        MoveWriteOffest(data.size());
    }
    //写入Buffer数据
    void WriteBuffer(Buffer &data)
    {
        return Write(data.ReadPosition(),data.ReadAbleSize());
    }
    //更新写入数据后的位置
    void WriteBufferAndPush(Buffer &data)
    {
        WriteBuffer(data);
        MoveWriteOffest(data.ReadAbleSize());
    }
    //读取数据
    void Read(void *buf,uint64_t len)
    {
        //1.要保证有数据并且是在可读范围内的
        assert(len <= ReadAbleSize());
        std::copy(ReadPosition(),ReadPosition() + len,(char*)buf);
    }
    //更新读取完之后的位置
    void ReadandPop(void *buf,uint64_t len)
    {
        Read(buf,len);
        MoveReadOffest(len);
    }
    //读取字符串数据
    std::string ReadAsString(uint64_t len)
    {
        assert(len <= ReadAbleSize());
        std::string buff;
        buff.resize(len);
        Read(&buff[0],len);
        return buff;
    }
    //更新读取完之后的位置
    std::string ReadAsStringPop(uint64_t len)
    {
        assert(len <= ReadAbleSize());
        std::string str = ReadAsString(len);
        MoveReadOffest(len);
        return str; 
    }
    //获取换行符
    char *FindCRLF()
    {
        char* res = (char*)memchr(ReadPosition(),'\n',ReadAbleSize());
        return res;
    }
    //获取一行数据
    std::string GetLine()
    {
        char* pos = FindCRLF();
        if(pos == nullptr) return "";
        return ReadAsString(pos - ReadPosition() + 1);//+1是为了把换行符也取出来
    }
    std::string GetLineAndPop()
    {
        std::string str = GetLine();
        MoveReadOffest(str.size());
        return str;
    }
    //清空缓冲区
    void Clear() {_reader_idx = _writer_idx = 0; }
    //
private:
    std::vector<char> _buffer;//使用vector进行内存空间管理
    uint64_t _reader_idx;//读偏移
    uint64_t _writer_idx;//写偏移
};

//Socket模块////////////////////////////////////////////////////////////////
class Socket
{
public:
    Socket():_sockfd(-1) {}
    Socket(int fd):_sockfd(fd) {}
    ~Socket() { if(_sockfd != -1) {
        close(_sockfd); 
        _sockfd = -1;} 
        }

    //创建套接字
    bool Create()
    {
        _sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//tcp() 0：表示让其自己选择
        if(_sockfd < 0)
        {
            logMessage(FATAL,"create socket error");
            //exit(SOCKET_ERR);
            return false;
        }
        logMessage(NORMAL,"create socket success");
        //int opt = 1;
        //setsockopt(_listensock,SOL_SOCKET,SO_REUSEADDR | SO_REUSEPORT,&opt,sizeof(opt));
        return true;
    }
    //绑定套接字
    bool Bind(const std::string &ip,uint16_t port)
    {
        struct sockaddr_in local;
        memset(&local,0,sizeof(local));
        //local.sin_addr.s_addr = inet_addr(ip.c_str());
        local.sin_addr.s_addr = INADDR_ANY;
        local.sin_family = AF_INET;
        local.sin_port = htons(port);
        socklen_t len = sizeof(struct sockaddr_in);
        //bind(_sockfd,(struct sockaddr*)&local,sizeof(local))
        if(bind(_sockfd,(struct sockaddr*)&local,len) < 0)
        {
            logMessage(FATAL,"socket bind error");
            //exit(BIND_ERR);
            return false;
        }
        logMessage(NORMAL,"socket bind success");
        return true;
    }
    //监听套接字
    bool Listen()
    {
        if(listen(_sockfd,backlog) < 0)
        {
            logMessage(FATAL,"socket listen error");
            //exit(LISTEN_ERR);`
            return false;
        }
        logMessage(NORMAL,"socket listen success");
        return true;
    }
    //发起连接
    bool Connect(const std::string &ip,uint16_t port)
    {
        struct sockaddr_in local;
        //memset(&local,0,sizeof(local));
        local.sin_addr.s_addr = inet_addr(ip.c_str());
        local.sin_family = AF_INET;
        local.sin_port = htons(port);
        socklen_t len = sizeof(struct sockaddr_in);
        if((connect(_sockfd,(const struct sockaddr*)&local,len)) < 0)
        {
            logMessage(FATAL,"socket connect error");
            //exit(CONNECT_ERR);
            return false;
        }
        logMessage(NORMAL,"socket connect success");
        return true;
    }
    //获取新连接
    int Accept()
    {
        int newfd = accept(_sockfd,nullptr,nullptr);
        if(newfd < 0)
        {
            logMessage(FATAL,"accept new sock error");
            return -1;
        }
        return newfd;
    }
    //接收数据
    ssize_t Recv(void* buf,size_t len,int flag = 0)
    {
        ssize_t ret = recv(_sockfd,buf,len,flag);
        if(ret <= 0)
        {
            //EAGAIN 表示的当前socket接收缓冲区中没有数据，在非阻塞情况下会出现该错误
            //EINTR 表示当前socket的阻塞等待，被信号打断了
            if(errno == EAGAIN || errno == EINTR)
                return 0;
            logMessage(FATAL,"socket inbuffer full");
            return -1;
        }
        return ret;
    }
    ssize_t NonBlockRecv(void *buf,size_t len)
    {
        return Recv(buf,len,MSG_DONTWAIT);//MSG_DONTWAIT表示当前接收为非阻塞接收
    }
    //发送数据
    ssize_t Send(const void *buf,size_t len,int flag = 0)
    {
        ssize_t ret = send(_sockfd,buf,len,flag);
        if(ret < 0)
        {
            if (errno == EAGAIN || errno == EINTR) 
                return 0;
            logMessage(FATAL,"socket send error");
            return -1;
        }
        return ret;
    }
    ssize_t NonBlockSend(void *buf,size_t len)
    {
        if(len == 0) return 0;
        return Send(buf,len,MSG_DONTWAIT);//MSG_DONTWAIT表示当前接收为非阻塞接收
    }
    //关闭套接字
    void Close()
    {
        if(_sockfd != -1){
            close(_sockfd);
            _sockfd = -1;
        }
    }
    //创建一个服务端链接
    bool CreateServer(uint16_t port,const std::string &ip = "0.0.0.0",bool block_flag = false)
    {
        //1.创建套接字 2.绑定地址  3.开始监听 4.设置为非阻塞  5.启动地址复用
        if(Create() == false) return false;
        if(block_flag) NonBlock();
        if(Bind(ip,port) == false) return false;
        if(Listen() == false) return false;
        ReuseAddress();
        return true;
    }
    //创建一个客户端连接
    bool CreateClient(uint16_t port,const std::string &ip)
    {
        //1.创建套接字  2.指向连接服务器
        if(Create() == false) return false;
        if(Connect(ip,port) == false) return false;
        return true;
    }
    //开启地址端口复用
    void ReuseAddress()
    {
        // int opt = 1;
        // setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR | SO_REUSEPORT,&opt,sizeof(opt));
        // int setsockopt(int fd, int leve, int optname, void *val, int vallen)
        int val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&val, sizeof(int));
        val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void*)&val, sizeof(int));
    }
    //设置非阻塞
    void NonBlock()
    {
        int flag = fcntl(_sockfd,F_GETFL,0);
        fcntl(_sockfd,F_SETFL,flag | O_NONBLOCK);
    }
    int Fd()
    {
        return _sockfd;
    }
private:
    int _sockfd; 
};
///////////////////////////////////////////////////////////////////////////////////
using EventCallback = std::function<void()>;//回调函数
class Poller;
class EventLoop;
class Channel
{
public:
    Channel(EventLoop *loop,int fd):_fd(fd),_events(0),_revents(0),_loop(loop) {}
    int Fd() {return _fd;}
    //将就绪事件设置进_revents,供调用解决就绪事件
    void SetRevent(uint32_t event) { _revents = event; }
    //获取事件
    uint32_t Events() {return _events;}
    //设置读事件回调
    void SetReadCallback(const EventCallback &cb) {_read_callback = cb;} 
    //设置写事件回调
    void SetWriteCallback(const EventCallback &cb) {_write_callback = cb;}
    //设置错误事件回调
    void SetErrorCallback(const EventCallback &cb) {_error_callback = cb;}
    //设置关闭事件回调
    void SetCloseCallback(const EventCallback &cb) {_close_callback = cb;}
    //设置所有事件回调
    void SetEventCallback(const EventCallback &cb) {_event_callback = cb;}
    //当前是否监控可读
    bool ReadAble() { return (_events & EPOLLIN); }
    //当前是否监控可写
    bool WriteAble() { return (_events & EPOLLOUT); }
    /**
     * 供EventLoop调用,后序调试修改
    */
    //启动读事件监控
    void EnableRead() { _events |= EPOLLIN; Update();}
    //启动写事件监控
    void EnableWrite() { _events |= EPOLLOUT; Update(); }
    //关闭读事件监控
    void DisableRead() { _events &= ~EPOLLIN; Update(); }
    //关闭写事件监控
    void DisableWrite() { _events &= ~EPOLLOUT; Update(); }
    //关闭所有事件监控
    void DisableAll() { _events = 0; Update(); }
    void Remove(); 
    //添加事件处理
    void Update(); 
    /**
     * 事件处理函数，有连接触发了事件，调用该函数处理
     * 1.再判断读回调(读、我方正常断开,对方正常断开)
     * 2.写回调
     * 3.错误回调EPOLLHUP(表现为一端或两端关闭,通常理解为异常挂断)
     * 4.判断是否触发任意事件回调if(_event_callback) _event_callback();
     *   该函数需要在读写事件之后进行判断
     *   对于关闭和错误事件之前判断，因为错误和关闭都会关闭对应文件描述符
    */
    void HandlerEvent()
    {
        /*先判断是否触发任意事件回调*/
        if((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
        {
            // if(_read_callback) _read_callback();
            // if(_event_callback) _event_callback();
            //if(_event_callback) _event_callback();
            if(_read_callback) _read_callback();   
        }
        if(_revents & EPOLLOUT)
        {
            // if(_write_callback) _write_callback();
            // if(_event_callback) _event_callback();
            //if(_event_callback) _event_callback();
            if(_write_callback) _write_callback();
        }
        else if(_revents & EPOLLERR)
            //if(_event_callback) _event_callback();
            if(_error_callback) _error_callback();
        else if(_revents & EPOLLHUP) 
            //if(_event_callback) _event_callback();
            if(_close_callback) _close_callback();
        if(_event_callback) _event_callback();

        // if((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
        // {
        //     // if(_read_callback) _read_callback();
        //     // if(_event_callback) _event_callback();
        //     if(_event_callback) _event_callback();
        //     if(_read_callback) _read_callback();   
        // }
        // if(_revents & EPOLLOUT)
        // {
        //     // if(_write_callback) _write_callback();
        //     // if(_event_callback) _event_callback();
        //     if(_event_callback) _event_callback();
        //     if(_write_callback) _write_callback();
        // }
        // if(_revents & EPOLLERR)
        //     if(_event_callback) _event_callback();
        //     if(_error_callback) _error_callback();
        // if(_revents & EPOLLHUP) 
        //     if(_event_callback) _event_callback();
        //     if(_close_callback) _close_callback();
        // //if(_event_callback) _event_callback();
    }
private:
    int _fd;
    //Poller *_poller;
    EventLoop *_loop;
    uint32_t _events;//当前所需监控的事件
    uint32_t _revents;//当前连接触发的事件
    EventCallback _read_callback;//读事件被触发的回调函数
    EventCallback _write_callback;//写事件被触发的回调函数
    EventCallback _error_callback;//错误事件被触发的回调函数
    EventCallback _close_callback;//连接断开事件被触发的回调函数
    EventCallback _event_callback;//任意事件被触发的回调函数
};
//////////////////////////////////////////////////////////////////////////////
#define MAX_EPOLLEVENTS 1024
const static int size = 128;
class Poller
{
public:
    Poller()
    {
        _epfd = epoll_create(MAX_EPOLLEVENTS);
        if(_epfd < 0)
        {
            logMessage(FATAL,"epoll_create error,code:%d,errstring:%s",errno,strerror(errno));
            exit(EPOLL_ERR);
        }
    }
    //添加或修改监控事件
    void UpdateEvent(Channel *channel)
    {
        bool ret = HasChannel(channel);
        if(ret == false)
        {
            _channels.insert(std::make_pair(channel->Fd(),channel));
            return Update(channel,EPOLL_CTL_ADD);
        }
        return Update(channel,EPOLL_CTL_MOD);
    }
    //移除监控
    void RemoveEvent(Channel* channel)
    {
        auto it = _channels.find(channel->Fd());
        if(it != _channels.end())
            _channels.erase(it);
        Update(channel,EPOLL_CTL_DEL);
    }
    //开始监控，返回连接
    void Poll(std::vector<Channel*> *active)
    {
        //对于timeout,后序修改
        int nfds = epoll_wait(_epfd,_evs,MAX_EPOLLEVENTS,-1);
        if(nfds < 0)
        {
            if(errno == EINTR)
                return;
            logMessage(FATAL,"epoll_wait error:%s",strerror(errno));
            exit(EPOLL_ERR);
        }
        for(int i = 0; i < nfds; i++)
        {
           auto it = _channels.find(_evs[i].data.fd);
           assert(it != _channels.end());
           it->second->SetRevent(_evs[i].events);
           active->push_back(it->second);
        }
        return;
    }
private:
    //对epoll的直接操作
    void Update(Channel *channel,int op)
    {
        int fd = channel->Fd();
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = channel->Events();
        int ret = epoll_ctl(_epfd,op,fd,&ev);
        if(ret < 0)
            logMessage(FATAL,"epoll ctl error!");
        return;
    }
    //判断一个Channel是否已经添加到了时间监控
    bool HasChannel(Channel *Channel)
    {
        auto it = _channels.find(Channel->Fd());
        if(it == _channels.end())
            return false;
        return true;
    }
private:
    int _epfd;
    struct epoll_event _evs[MAX_EPOLLEVENTS];
    std::unordered_map<int,Channel*> _channels;
};


using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
//定时的任务类
class Channel;
class EventLoop;
class TimerTask
{
public:
    TimerTask(uint64_t id,uint32_t delay,const TaskFunc &cb)
    :_id(id),_timeout(delay),_task_cb(cb),_canceled(false)
    {}
    ~TimerTask()
    {
        //处理定时任务,如果没有被设置取消任务
        if(_canceled == false) _task_cb();//定时任务
        _release();//删除执行后的对象信息
    }
    void SetRelease(const ReleaseFunc& cb) { _release = cb; }//用于设置回调的release对象
    uint32_t DelayTime() { return _timeout;}
    void canceled() { _canceled = true; }
private:
    uint64_t _id; //定时器任务对象ID
    uint32_t _timeout;//定时任务的超时时间
    bool _canceled; //用于取消任务(true-表示被取消，false-表示不被取消)
    TaskFunc _task_cb;//定时器对象所需执行的定时任务
    ReleaseFunc _release;//用于删除TimeWheel中保存的定时器对象的信息
};

//定时器轮子(队列)
class Channel;
class EventLoop;
class TimerTask;
class TimerWheel
{
public:
    TimerWheel(EventLoop *loop)
    :_capacity(60),_tick(0),_wheel(_capacity)
    ,_timerfd(CreatTimerfd()),_loop(loop)
    ,_timer_channel(new Channel(_loop,_timerfd))
    {
        _timer_channel->SetReadCallback(std::bind(&TimerWheel::OnTime,this));
        _timer_channel->EnableRead();
    }
    ~TimerWheel() 
    {}
    //添加定时任务
    //在后序经过EventLoop会把所有的任务放大一个线程中进行处理
    // void TimerAdd(uint64_t id,uint32_t delay,const TaskFunc &cb)
    // {
    //     PtrTask pt(new TimerTask(id,delay,cb));//通过指针添加定时任务TimerTask
    //     pt->SetRelease(std::bind(&TimerWheel::RemoveTimer,this,id));
    //     int pos = (_tick + delay) % _capacity;
    //     _wheel[pos].push_back(pt);
    //     _timers[id] = WeakTask(pt);
    // }
    void TimerAddInloop(uint64_t id,uint32_t delay,const TaskFunc &cb)
    {
        PtrTask pt(new TimerTask(id,delay,cb));//通过指针添加定时任务TimerTask
        pt->SetRelease(std::bind(&TimerWheel::RemoveTimer,this,id));
        int pos = (_tick + delay) % _capacity;
        _wheel[pos].push_back(pt);
        _timers[id] = WeakTask(pt);
    }
    //(刷新/延迟)定时任务
    // void TimerRefresh(uint64_t id)
    // {
    //     //通过保存的定时器对象的weak_ptr构造一个shared_ptr出来，添加到轮子当中
    //     auto it = _timers.find(id);
    //     if(it == _timers.end())
    //         return;//没有找到定时任务，没法刷新，直接退出
    //     PtrTask pt = it->second.lock();//lock获取weak_ptr管理对象对应的shared_ptr
    //     int delay = pt->DelayTime();
    //     int pos = (_tick + delay) % _capacity;
    //     _wheel[pos].push_back(pt);
    // }
    void TimerRefreshInloop(uint64_t id)
    {
        //通过保存的定时器对象的weak_ptr构造一个shared_ptr出来，添加到轮子当中
        auto it = _timers.find(id);
        if(it == _timers.end())
            return;//没有找到定时任务，没法刷新，直接退出
        PtrTask pt = it->second.lock();//lock获取weak_ptr管理对象对应的shared_ptr
        int delay = pt->DelayTime();
        int pos = (_tick + delay) % _capacity;
        _wheel[pos].push_back(pt);
    }
    //用于取消定时任务
    // void TimerCancel(uint64_t id)
    // {
    //     auto it = _timers.find(id);
    //     if(it == _timers.end())
    //         return;
    //     PtrTask pt = it->second.lock();
    //     if(pt) pt->canceled();
    // }
    void TimerCancelInloop(uint64_t id)
    {
        auto it = _timers.find(id);
        if(it == _timers.end())
            return;
        PtrTask pt = it->second.lock();
        if(pt) pt->canceled();
    }
    //该函数应该一秒执行一次，相当于秒针向后走了一步
    void RunTimerTask()
    {
        _tick = (_tick + 1) % _capacity;
        _wheel[_tick].clear();//清除指定位置的数组，就会把数组中保存的所有管理定时器对象的shared_ptr释放掉
    }
// private:
public:
    //判断定时任务是否存在，根据id把该
    void RemoveTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if(it != _timers.end())
            _timers.erase(id);
    }
    static int CreatTimerfd()
    {
        /*int timerfd_settime(int fd, int flags,
                           const struct itimerspec *new_value,
                           struct itimerspec *old_value);*/
        int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
        if(timerfd < 0)
        {
            logMessage(FATAL,"create timerfd error!");
            exit(TIMERFD_ERR);
        }
        struct itimerspec itime;
        itime.it_value.tv_sec = 1;
        itime.it_value.tv_nsec = 0;//第一次超时时间为1s后
        itime.it_interval.tv_sec = 1;
        itime.it_interval.tv_nsec = 0;//第一次超时后，每次超时的间隔时间
        timerfd_settime(timerfd,0,&itime,nullptr);
        return timerfd;
    }
    int ReadTimerfd()
    {
        uint64_t times;
        int ret = read(_timerfd,&times,8);
        if(ret < 0)
        {
            logMessage(FATAL,"ReadTimerfd error!");
            exit(READTIMERFD_ERR);
        }
        return times;
    }
    void OnTime()
    {
        int times = ReadTimerfd();
        for(int i = 0; i < times; i++)
            RunTimerTask();
    }
    void TimerAdd(uint64_t id,uint32_t delay,const TaskFunc &cb);
    
    void TimerRefresh(uint64_t id);
    
    void TimerCancel(uint64_t id);
    
    //是否存在某个定时任务(有线程安全,只能在对应EventLoop中调用)
    bool HasTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if(it == _timers.end())
            return false;
        return true;
    }
private:
    int _tick; //当前的秒针，走到哪里释放哪里，就执行哪里的任务
    int _capacity;//表示该定时器表盘的最大数量，也就是最大延时时间
    using WeakTask = std::weak_ptr<TimerTask>;//
    using PtrTask = std::shared_ptr<TimerTask>;//时间轮中的第二个参数，存放的是每个节点所对应的任务指针,可以通过该指针访问该任务(通过创建该指针添加任务)
    std::vector<std::vector<PtrTask>> _wheel;//时间轮当中的每一个节点都是一个vecto，每个节点当中存放一个PtrTask
    std::unordered_map<uint64_t,WeakTask> _timers;//用于通过定时器任务id，来获取到每一个任务
    int _timerfd;//定时器描述符
    EventLoop *_loop;
    std::unique_ptr<Channel> _timer_channel;
};

//EventLoop模块/////////////////////////////////////////
/**对事件进行监控*/
using Functor = std::function<void()>;//
class Channel;
class TimerWheel;
class EventLoop
{
public:
    EventLoop()
    :_thread_id(std::this_thread::get_id())
    ,_event_fd(CreateEventFd())
    ,_event_channel(new Channel(this,_event_fd))
    ,_timer_wheel(this)
    {
        //给eventfd添加可读事件回调函数，读取eventfd事件通知次数
        _event_channel->SetReadCallback(std::bind(&EventLoop::ReadEventfd,this));
        //启动eventfd的读事件监控
        _event_channel->EnableRead();
    }
    //判断要执行的任务是否在当前线程中
    void RunInLoop(const Functor &cb)
    {
        if(IsInLoop())
            return cb();
        return QueueInLoop(cb);
    }
    //将任务压入任务池
    void QueueInLoop(const Functor &cb)
    {
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _tasks.push_back(cb);
        }
        //唤醒所有可能因为没有事件就绪而导致epoll的阻塞;
        WeakUpEventFd();
    }
    //判断当前线程是否是EventLoop所对应的线程
    bool IsInLoop()
    {
        return (_thread_id == std::this_thread::get_id());
    }
    void AssertInLoop() 
    {
        assert(_thread_id == std::this_thread::get_id());
    }
    //添加/修改描述符的事件监控
    void UpdateEvent(Channel *channel)
    {
        return _poller.UpdateEvent(channel);
    }
    //删除描述符事件监控
    void RemoveEvent(Channel *channel)
    {
        return _poller.RemoveEvent(channel);
    }
    /**对定时器操作函数*/
    void TimerAdd(uint64_t id,uint32_t delay,const TaskFunc &cb)
    {
        return _timer_wheel.TimerAdd(id,delay,cb);
    }
    void TimerRefresh(uint64_t id)
    {
        return _timer_wheel.TimerRefresh(id);
    }
    void TimerCancel(uint64_t id)
    {
        return _timer_wheel.TimerCancel(id);
    }
    //判断是否还有任务
    bool HasTimer(uint64_t id)
    {
        return _timer_wheel.HasTimer(id);
    }
    
    //启动(监控，处理，执行)
    void Start()
    {
        while(1)
        {
            //1.事件监控
            std::vector<Channel*> actives;
            _poller.Poll(&actives);
            //2.事件处理
            for(auto &channel : actives)
                channel->HandlerEvent();
            //执行任务
            RunAllTask();
        }
        
    }
public:
    //执行任务池中的全部任务
    void RunAllTask()
    {
        std::vector<Functor> functor;
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _tasks.swap(functor);
        }
        for(auto &f : functor)
            f();
        return;
    }

    static int CreateEventFd()
    {
        int efd = eventfd(0,EFD_CLOEXEC | EFD_NONBLOCK);
        if(efd < 0)
        {
            logMessage(WARNING,"CreateEventFd error!");
            exit(CREATEVENTFD_ERR);
        }
        return efd;
    }
    //
    void ReadEventfd()
    {
        uint64_t res = 0;
        int ret = read(_event_fd,&res,sizeof(res));
        if(ret < 0)
        {
            //EINTR:被信号打断   EAGAIN:没有数据可读
            if(errno == EINTR || errno == EAGAIN)
                return;
            logMessage(WARNING,"read eventfd error!");
            exit(READEVENTFD_ERR);
        }
        return ;
    }
    //唤醒所有可能因为没有事件就绪而导致epoll的阻塞;
    void WeakUpEventFd()
    {
        uint64_t val = 1;
        int ret = write(_event_fd,&val,sizeof(val));
        if(ret < 0)
        {
            if(errno == EINTR)
                return;
            logMessage(WARNING,"write eventfd error!");
            exit(WRITEEVENTFD_ERR);
        }
        return ;
    }
private:
    int _event_fd;//event唤醒IO事件监控可能导致的阻塞
    std::thread::id _thread_id;//线程ID
    Poller _poller;//对所有描述符的事件监控
    std::unique_ptr<Channel> _event_channel;
    std::vector<Functor> _tasks;//任务池
    std::mutex _mutex;//保障任务池操作安全
    TimerWheel _timer_wheel;//定时器对象
};

//LoopThread
class LoopThread
{
public:
    LoopThread():_loop(nullptr)
    ,_thread(std::thread(&LoopThread::ThreadEntry,this))
    {}
    /* 用于获取当前线程所关联的EventLoop对象,方便后序实例化操作*/
    EventLoop *GetLoop()
    {
        EventLoop *loop = nullptr;
        {
            std::unique_lock<std::mutex> lock(_mutex);//加锁
            _cond.wait(lock,[&](){ return _loop != nullptr; });//loop为空时一直阻塞
            loop = _loop;
        }
        return loop;
    }
private:
    /* 实例化 EventLoop对象，并且开始运行EventLoop模块的功能*/
    void ThreadEntry()
    {
        EventLoop loop;
        {
            std::unique_lock<std::mutex> lock(_mutex);//加锁
            _loop = &loop;
            _cond.notify_all();
        }
        loop.Start(); 
    }
private:
    std::thread _thread;//线程
    EventLoop *_loop;//在线程内实例化
    std::mutex _mutex;//锁
    std::condition_variable _cond;//互斥变量
};

/* LoopThreadPool模块*/
class LoopThreadPool
{
public:
    LoopThreadPool(EventLoop* baseloop):_thread_count(0),_next_loop_idx(0)
    ,_base_loop(baseloop)
    {}
    //启动
    void Create()
    {
        //当有从属线程的时候才需要进行分配
        if(_thread_count > 0)
        {
            _threads.resize(_thread_count);
            _loops.resize(_thread_count);
            for(int i = 0; i < _thread_count; i++)
            {
                _threads[i] = new LoopThread();
                _loops[i] = _threads[i]->GetLoop();
            }
        }
        //没有时，直接返回即可
        return ;
    }
    //设置线程数量
    void SetThreadPoolCount(int count) { _thread_count = count; }
    //获取下一个
    EventLoop *NextLoop()
    {
        if(_thread_count == 0)
            return _base_loop;
        _next_loop_idx = (_next_loop_idx + 1) % _thread_count;
        return _loops[_next_loop_idx];
    }
private:
    int _thread_count;//设置从属线程的数量
    int _next_loop_idx;//设置下一个从属线程下标
    EventLoop* _base_loop;//主线程(主要当_thread_count=0时，不创建从属线程，直接在主线程中执行)
    std::vector<LoopThread*> _threads;//存放所有LoopThread对象
    std::vector<EventLoop*> _loops;//配置当_thread_count>0时，从_loops中心性线程EventLoop的分配
};

//Connection
/**
 * DISCONECTED-->连接关闭状态
 * CONNECTING-->连接启动状态
 * CONNECTED-->连接建立完成状态
 * DISCONNECTING-->待关闭状态
*/
class Connection;
typedef enum 
{
    CONNECTING,
    CONNECTED,
    DISCONNECTING,
    DISCONECTED
    
}ConnStatu;
using PtrConnection = std::shared_ptr<Connection>;
using ConnectedCallback = std::function<void(const PtrConnection&)>;
using MessageCallback = std::function<void(const PtrConnection&,Buffer *)>;
using CloseCallback = std::function<void(const PtrConnection&)>;
using AnyEventCallback = std::function<void(const PtrConnection&)>;

class Connection : public std::enable_shared_from_this<Connection>
{
public://weak_ptr
    Connection(EventLoop* loop,uint64_t conn_id,int sockfd)
    :_conn_id(conn_id),_sockfd(sockfd),_socket(_sockfd)
    ,_enable_inactive_release(false),_loop(loop),_statu(CONNECTING)
    ,_channel(loop,_sockfd)
    {
        _channel.SetCloseCallback(std::bind(&Connection::HandleClose,this));
        _channel.SetErrorCallback(std::bind(&Connection::HandleError,this));
        _channel.SetEventCallback(std::bind(&Connection::HandleEvent,this));
        _channel.SetReadCallback(std::bind(&Connection::HandleRead,this));
        _channel.SetWriteCallback(std::bind(&Connection::HandleWrite,this));
    }
    ~Connection()
    {
        logMessage(DEBUG,"release connection:%p",this);
    }
    //获取管理的文件描述符
    int Fd() { return _sockfd; }
    //获取连接ID
    int Id() { return _conn_id; }
    //判断是否处于连接状态
    bool Connected() { return (_statu == CONNECTED); }
    //发送数据，将数据拷贝到发送缓冲区中，启动写事件监控
    /**
     * 外界传⼊的data，可能是个临时的空间，我们现在只是把发送操作压⼊了任务池，有
       可能并没有被⽴即执⾏
     * 
    */
    // void SendBuff(const char* data,size_t len)
    // {
    //     Buffer buf;
    //     buf.WriteAndPush((void*)data,len);
    //     _loop->RunInLoop(std::bind(&Connection::SendBuffInLoop,this,std::move(buf)));
    // }
    // //char类型
    // void Send(const char* data,size_t len)
    // {
    //     _loop->RunInLoop(std::bind(&Connection::SendInLoop,this,data,len));
    // }
    void Send(const char* data,size_t len)
    {
        Buffer buf;
        buf.WriteAndPush((void*)data,len);
        _loop->RunInLoop(std::bind(&Connection::SendInLoop,this,std::move(buf)));
    }
    //关闭连接(需要判断对应关闭条件)
    void ShutDown()
    {
        _loop->RunInLoop(std::bind(&Connection::ShutDownInLoop,this));
    }
    //启动非活跃连接销毁
    void EnableInactiveRelease(int sec)
    {
        _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop,this,sec));
    }
    //关闭非活跃连接销毁
    void CancelInactiveRelease()
    {
        _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop,this));
    }
    //更新上下文协议-->必须在EventLoop中立即执行，防止新事件触发后，处理的时候，
    //切换任务还没被执行--会导致数据使用了原协议处理
    void Upgrade(const Any &connect,const ConnectedCallback& conn,
                 const MessageCallback& msg, const CloseCallback& closed,
                 const AnyEventCallback& event)
    {
        _loop->AssertInLoop();
        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop,this,connect,conn,msg,closed,event));
    }
    void Release() { _loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop,this)); }
    //连接获取之后，所处的状态下进行各种设置(Channel设置事件回调，启动读监控_connected_callback) 
    void Established()  
    {
        _loop->RunInLoop(std::bind(&Connection::EstablishedInLoop,this));
    }         
    //设置上下文
    void SetContext(const Any& context) { _context = context; }
    //获取上下文,返回指针
    Any* GetContext() { return &_context; }
    void SetConnectedCallback(const ConnectedCallback& cb) { _connected_callback = cb; }
    void SetMessageCallback(const MessageCallback& cb) { _message_callback = cb; }
    void SetClosedCallback(const CloseCallback& cb) { _close_callback = cb; }
    void SetAnyEventCallback(const AnyEventCallback& cb) { _event_callback = cb; }
    void SetSrvClosedCallback(const CloseCallback& cb) { _server_close_callback = cb; }
private:
    /*channel相关事件回调函数*/
    //读事件触发后调用的函数
    void HandleRead()
    {
        //1.接收Socket中数据，放到inbuffer中
        char buffer[65536];
        ssize_t ret = _socket.NonBlockRecv(buffer,sizeof(buffer) - 1);
        if(ret < 0)
        {
            //出错了，但是不能直接关闭连接，需要交给ShutDownInLoop()处理
            return ShutDownInLoop();
        }
        //这里等于0表示的是没有读取到数据，而不是断开连接了
        //此时把数据放到对应的输入缓冲区中,并把下标向后偏移
        _in_buffer.WriteAndPush(buffer,ret);
        if(_in_buffer.ReadAbleSize() > 0)
        {
            /**
             * 从继承中的class Connection : public enable_shared_from_this<Connection>
             * enable_shared_from_this<Connection>会给我们提供一个weak_ptr
             * 我们从weak_ptr中获取对应shared_from_this()
             * 并能从中获得出一个shared_ptr
             * (shared_from_this()--从当前对象自身获取自身的shared_ptr管理对象)
            */
            return _message_callback(shared_from_this(), &_in_buffer);
        }
    }
    //写事件触发后调用的函数
    void HandleWrite()
    {
        ssize_t ret = _socket.NonBlockSend(_out_buffer.ReadPosition(),_out_buffer.ReadAbleSize());
        if(ret < 0)
        {
            if(_in_buffer.ReadAbleSize() > 0)
                _message_callback(shared_from_this(),&_in_buffer);
            //return ReleaseInLoop();//真正的释放
            return Release();
        }
        _out_buffer.MoveReadOffest(ret);//?为什么是读偏移量
        //如果没有数据待发送了，就关闭写事件监控
        if(_out_buffer.ReadAbleSize() == 0)
        {
            _channel.DisableWrite();
            //如果当前连接还是待关闭状态，有数据发送完释放，没有则直接释放
            if(_statu == DISCONNECTING)
                //return ReleaseInLoop();
                return Release();
        }
        return;
    }
    //描述符触发错误后回调函数
    void HandleError()
    {
        return HandleClose();
    }
    //描述符触发关闭后回调函数
    void HandleClose()
    {
        if(_in_buffer.ReadAbleSize() > 0)
            _message_callback(shared_from_this(),&_in_buffer);
        //return ReleaseInLoop();
        return Release();
    }
    //描述符触发任意事件回调函数
    /**
     * 1.刷新连接的活跃度--延迟定时任务的销毁
     * 2.调用组件使用者设置的任意事件回调
    */
    void HandleEvent()
    {
        if(_enable_inactive_release == true) { _loop->TimerRefresh(_conn_id); }
        if(_event_callback) { _event_callback(shared_from_this()); }
    }
    // //Buff类型--将数据拷贝到发送缓冲区中，启动可读事件监控(不是真的可写)
    // void SendBuffInLoop(Buffer &buf)
    // {
    //     //const char* data,size_t len
    //     //判断连接是否已经关闭了
    //     if(_statu == DISCONECTED) return;
    //     //把数据放到写缓冲区中
    //     _out_buffer.WriteBufferAndPush(buf);
    //     //判断是否启动了写事件监控,没有监控,那么就启动写事件监控
    //     if(_channel.WriteAble() == false)
    //         _channel.EnableWrite();
    // }
    // //char类型
    // void SendInLoop(const char* data,size_t len)
    // {
    //     //const char* data,size_t len
    //     //判断连接是否已经关闭了
    //     if(_statu == DISCONECTED) return;
    //     //把数据放到写缓冲区中
    //     _out_buffer.WriteAndPush((void*)data,len);
    //     //判断是否启动了写事件监控,没有监控,那么就启动写事件监控
    //     if(_channel.WriteAble() == false)
    //         _channel.EnableWrite();
    // }
    void SendInLoop(Buffer &buf)
    {
        //const char* data,size_t len
        //判断连接是否已经关闭了
        if(_statu == DISCONECTED) return;
        //把数据放到写缓冲区中
        _out_buffer.WriteBufferAndPush(buf);
        //判断是否启动了写事件监控,没有监控,那么就启动写事件监控
        if(_channel.WriteAble() == false)
            _channel.EnableWrite();
    }
    //不是直接关闭连接(半关闭)
    void ShutDownInLoop()
    {
        _statu = DISCONNECTING;
        if(_in_buffer.ReadAbleSize() > 0)
            if(_message_callback) _message_callback(shared_from_this(),&_in_buffer);
        if(_out_buffer.ReadAbleSize() > 0)
            if(_channel.WriteAble() == false)
                _channel.EnableWrite();
        if(_out_buffer.ReadAbleSize() == 0)
            //ReleaseInLoop();
            Release();
    }
    //启动非活跃连接销毁
    void EnableInactiveReleaseInLoop(int sec)
    {
        //先将标志位设置为true
        _enable_inactive_release = true;
        //如果之前已经被设置过了，那么此时刷新一下即可
        if(_loop->HasTimer(_conn_id))
            return _loop->TimerRefresh(_conn_id);
        //没有就新增
        //_loop->TimerAdd(_conn_id,sec,std::bind(&Connection::ReleaseInLoop,this));
        _loop->TimerAdd(_conn_id,sec,std::bind(&Connection::Release,this));
    }
    //取消非活跃连接销毁
    void CancelInactiveReleaseInLoop()
    {
        //先将标志位设置为false
        _enable_inactive_release = false;
        //该定时任务存在就将其销毁
        if(_loop->HasTimer(_conn_id))
            _loop->TimerCancel(_conn_id);
    }
    //更新上下文协议
    void UpgradeInLoop(const Any &connect,const ConnectedCallback& conn,
                 const MessageCallback& msg, const CloseCallback& closed,
                 const AnyEventCallback& event)
    {
        _context = connect;
        _connected_callback = conn;
        _message_callback = msg;
        _close_callback = closed;
        _event_callback = event;
        
    }
    //void Release();
    //实际的释放接口
    void ReleaseInLoop()
    {
        //1.设置连接状态
        _statu = DISCONECTED;
        //2.移除连接事件监控
        _channel.Remove();
        //3.关闭描述符
        _socket.Close();
        //4.清空该线程定时器队列中的定时销毁任务
        if(_loop->HasTimer(_conn_id))
            CancelInactiveReleaseInLoop();
        //5.调用关闭回调函数，避免先移除服务器管理的连接信息二导致connection被释放
        if(_close_callback)
            _close_callback(shared_from_this());
        //6.移除服务器内部管理的连接信息
        if(_server_close_callback)
            _server_close_callback(shared_from_this());
    }
    //连接获取之后，所处的状态下进行各种设置(Channel设置事件回调，启动读监控)
    void EstablishedInLoop()
    {
        //1.修改对应的连接状态 3.调用回调函数
        assert(_statu == CONNECTING);
        _statu = CONNECTED;
        //2.启动读事件监控
        _channel.EnableRead();
        //3.调用回调函数
        if(_connected_callback) 
            _connected_callback(shared_from_this());
    }
private:
    uint64_t _conn_id; //连接唯一ID，便于对连接的管理
    Socket _socket; //对于套接字的管理
    int _sockfd;//配套Socket的文件描述符
    Channel _channel;//连接事件的管理
    Buffer _in_buffer;//输入缓冲区
    Buffer _out_buffer;//输出缓冲区
    Any _context;//请求的接收处理上下文(协议控制)
    bool _enable_inactive_release;//控制启动非活跃链接(false-不启动默认)
    EventLoop *_loop;//连接所关联的一个EventLoop
    ConnStatu _statu;//连接状态管理
    /**
     * 回调函数的操作
     * 是让用户进行设置,供用户调用使用
     * ConnectedCallback _connected_callback -->连接管理回调
     * MessageCallback _message_callback-->信息管理回调
     * CloseCallback _close_callback-->挂壁连接回调
     * AnyEventCallback _event_callback-->任意事件回调
    */
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    CloseCallback _close_callback;
    AnyEventCallback _event_callback;
    /**
     * 组件内的连接关闭回调--组件内进行设置
     * 因为服务器组件会把所有的连接管理起来，一旦某个连接要关闭
     * 就应该从管理的地方移除掉其信息
    */
    CloseCallback _server_close_callback;
};


//Accept
using AcceptCallBack = std::function<void(int)>;
class Acceptor
{
public:
    /**
     * 不能将启动读事件监控，放到构造函数中
     * 必须在设置回调函数之后，再去启动
     * 不然可能会造成启动监控后，立即有事件处理的时候回调函数还没设置
     * 新连接得不到处理，并且资源泄漏
    */
    Acceptor(EventLoop *loop,int port)
    :_loop(loop),_socket(CreateServer(port)),_channel(loop,_socket.Fd())
    {
        _channel.SetReadCallback(std::bind(&Acceptor::HandleRead,this));
    }
    void SetAcceptCallBack(const AcceptCallBack& cb) { _accept_callback = cb; }
    //所以单独将读事件监控拿出来，放到后面设置调用
    void Listen()
    {
        _channel.EnableRead();
    }
private:
    void HandleRead()
    {
        std::cout << "accept handle read" << std::endl;
        int newfd = _socket.Accept();
        if(newfd < 0) return ;
        if(_accept_callback) _accept_callback(newfd);
    }
    int CreateServer(int port)
    {
        bool ret = _socket.CreateServer(port);
        assert(ret == true);
        return _socket.Fd();
    }
private:
    Socket _socket;
    EventLoop *_loop;
    Channel _channel;
    AcceptCallBack _accept_callback;
};

/* TcpServer*/
using PtrConnection = std::shared_ptr<Connection>;
using Functor = std::function<void()>;
using ConnectedCallback = std::function<void(const PtrConnection&)>;
using MessageCallback = std::function<void(const PtrConnection&,Buffer *)>;
using CloseCallback = std::function<void(const PtrConnection&)>;
using AnyEventCallback = std::function<void(const PtrConnection&)>;
class TcpServer
{
public:
    TcpServer(int port):_port(port),_next_id(0),_enable_inactive_release(false)
    ,_acceptor(&_baseloop,port),_pool(&_baseloop)
    {
        _acceptor.SetAcceptCallBack(std::bind(&TcpServer::NewConnection,this,std::placeholders::_1));
        _acceptor.Listen();//将监听套接字挂到baseloop上
    }
    void SetThreadCount(int count) { return _pool.SetThreadPoolCount(count); }
    void SetConnectedCallback(const ConnectedCallback& cb) { _connected_callback = cb; }
    void SetMessageCallback(const MessageCallback& cb) { _message_callback = cb; }
    void SetClosedCallback(const CloseCallback& cb) { _close_callback = cb; }
    void SetAnyEventCallback(const AnyEventCallback& cb) { _event_callback = cb; }
    //添加非活跃链接
    void EnableInactiveRelease(int timeout)
    {
        _timeout = timeout;
        _enable_inactive_release = true;
    }
    //定时任务的添加
    void RunAfter(const Functor &task,int delay)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop,this,task,delay));
    }
    //启动
    void Start()
    {
        _pool.Create();//创建线程池中的从属线程
        _baseloop.Start();
    }
private:
    //(添加)为新连接构造一个Connection进行管理
    void NewConnection(int fd)
    {
        _next_id++;
        PtrConnection conn(new Connection(_pool.NextLoop(),_next_id,fd));
        conn->SetMessageCallback(_message_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetClosedCallback(_close_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection,this,std::placeholders::_1));
        if(_enable_inactive_release == true)//看是否启动非活跃连接销毁
            conn->EnableInactiveRelease(_timeout);
        conn->Established();//初始化
        _conns.insert(std::make_pair(_next_id,conn));//添加保存
    }
    //(删除)
    void RemoveConnectionInLoop(const PtrConnection &conn)
    {
        int id = conn->Id();
        auto it = _conns.find(id);
        if(it != _conns.end())
            _conns.erase(it);
    }
    void RemoveConnection(const PtrConnection &conn)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop,this,conn));
    }
    void RunAfterInLoop(const Functor &task,int delay)
    {
        _next_id++;
        _baseloop.TimerAdd(_next_id,delay,task);
    }
private:
    int _port;
    uint64_t _next_id;//对应连接数量(自增)
    int _timeout;//非活跃连接的时间限制
    bool _enable_inactive_release;//判断非活跃连接的判断条件(默认false关闭)
    Acceptor _acceptor;//建通套接字管理对象
    EventLoop _baseloop;//主线程baseloop，负责监听事件的处理
    LoopThreadPool _pool;//从属EventLoop线程池
    std::unordered_map<uint64_t,PtrConnection> _conns;//保存所有的连接对象(shared_ptr)
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    CloseCallback _close_callback;
    AnyEventCallback _event_callback;
};

class NetWork
{
public:
    NetWork()
    {
        logMessage(NORMAL,"SIGPIPE INIT");
        signal(SIGPIPE, SIG_IGN);
    }
};
static NetWork nw;

//移除监控,在EventLoop中调用实现
void Channel::Remove() {return _loop->RemoveEvent(this); }
//添加事件处理
void Channel::Update() {return _loop->UpdateEvent(this); }

void TimerWheel::TimerAdd(uint64_t id,uint32_t delay,const TaskFunc &cb)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerAddInloop,this,id,delay,cb));
}
void TimerWheel::TimerRefresh(uint64_t id)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInloop,this,id));
}
void TimerWheel::TimerCancel(uint64_t id)
{ 
    _loop->RunInLoop(std::bind(&TimerWheel::TimerCancelInloop,this,id));
}
#endif
